package com.ruihang.generalibrary.ui.widget;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Looper;
import android.support.v7.widget.AppCompatTextView;
import android.text.Html;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.TextUtils;
import android.text.style.ScaleXSpan;
import android.util.AttributeSet;

import com.ruihang.generalibrary.utils.FontProvider;

public class CustomFontTextView extends AppCompatTextView {

    private float spacing = Spacing.NORMAL;
    private CharSequence originalText = "";
    private boolean isSpacing = false;
    private Handler handler = new Handler(Looper.getMainLooper());
    private boolean isSetNewDrawable = false;

    public CustomFontTextView(Context context) {
        super(context);
        init(context);
    }

    public CustomFontTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public CustomFontTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context);
    }

    private void init(Context context) {
        if (FontProvider.useCustomFont) {
            setTypeface(FontProvider.getTypeface(context));
        }
    }

    private void applySpacing() {
        if (this == null || this.originalText == null)
            return;
        if (!isSpacing) {
            super.setText(new SpannableString(originalText), BufferType.NORMAL);
            return;
        }
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < originalText.length(); i++) {
            builder.append(originalText.charAt(i));
            if (i + 1 < originalText.length()) {
                builder.append("\u00A0");
            }
        }
        SpannableString finalText = new SpannableString(builder.toString());

        if (builder.toString().length() > 1) {
            for (int i = 1; i < builder.toString().length(); i += 2) {

                if (!isNumberOrEng(finalText.charAt(i - 1))) {
                    finalText.setSpan(new ScaleXSpan((spacing + 1) / 10), i, i + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                }

            }
        }
        super.setText(finalText, BufferType.SPANNABLE);
    }

    public class Spacing {
        public final static float NORMAL = 0;
    }

    public float getSpacing() {
        return this.spacing;
    }

    public void setSpacing(float spacing) {
        this.spacing = spacing;
        isSpacing = true;
        applySpacing();
    }

    @Override
    public void setText(CharSequence text, BufferType type) {
        if (isAutoline) {
            originalText = ToDBC(text.toString());
        } else {
            originalText = text;
        }
        applySpacing();
    }

    @Override
    public CharSequence getText() {
        return originalText;
    }

    private boolean isAutoline = false;

    public void setAutoLine(boolean isAutoline) {
        this.isAutoline = isAutoline;
    }

    public static String ToDBC(String input) {
        char[] c = input.toCharArray();
        for (int i = 0; i < c.length; i++) {
            if (c[i] == 12288) {
                c[i] = (char) 32;
                continue;
            }
            if (c[i] > 65280 && c[i] < 65375)
                c[i] = (char) (c[i] - 65248);
        }
        return new String(c);
    }

    private boolean isNumberOrEng(char ch) {
        return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') || ('0' <= ch && ch <= '9');
    }

    /**
     * 设置文字关键子数组红色高亮
     *
     * @param text      全部文本
     * @param highLight 需要高亮显示的关键词组
     */
    public void setText(String text, String... highLight) {
        setTextWithColor(text, "ff5961", highLight);
    }

    /**
     * 设置文字关键字高亮,并指定对应的颜色
     *
     * @param text      全部文本
     * @param textColor 高亮显示文字的颜色
     * @param highLight 需要高亮显示的关键词组
     */
    public void setTextWithColor(String text, String textColor, String... highLight) {
        if (TextUtils.isEmpty(text)) {
            return;
        }
        for (int i = 0; i < highLight.length; i++) {
            for (int j = i + 1; j < highLight.length; j++) {
                if (highLight[j].indexOf(highLight[i]) != -1) {
                    String h = highLight[j];
                    highLight[j] = highLight[i];
                    highLight[i] = h;
                }
            }
        }
        for (String h : highLight) {
            text = text.replaceAll(h, "<font color=\"#" + textColor + "\">" + h + "</font>");
        }
        setText(Html.fromHtml(text));
    }

    /**
     * 调用使drawable图标渐进变大
     */
    public void setDrawableEnlarge() {
        final Drawable[] dr = this.getCompoundDrawables();
        if (dr.length > 0) {
            isSetNewDrawable = false;
            final Drawable drawable = dr[0];
            if (null != drawable) {
                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        drawable.setBounds(0, 0, drawable.getMinimumWidth() * 9 / 8, drawable.getMinimumHeight() * 9 / 8);
                        setThisDrawable(drawable);
                    }
                }, 10);
                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        drawable.setBounds(0, 0, drawable.getMinimumWidth() * 8 / 7, drawable.getMinimumHeight() * 8 / 7);
                        setThisDrawable(drawable);
                    }
                }, 20);
                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        drawable.setBounds(0, 0, drawable.getMinimumWidth() * 7 / 6, drawable.getMinimumHeight() * 7 / 6);
                        setThisDrawable(drawable);
                    }
                }, 30);
                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        drawable.setBounds(0, 0, drawable.getMinimumWidth() * 6 / 5, drawable.getMinimumHeight() * 6 / 5);
                        setThisDrawable(drawable);
                    }
                }, 45);
                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        drawable.setBounds(0, 0, drawable.getMinimumWidth() * 5 / 4, drawable.getMinimumHeight() * 5 / 4);
                        setThisDrawable(drawable);
                    }
                }, 65);
                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        drawable.setBounds(0, 0, drawable.getMinimumWidth() * 4 / 3, drawable.getMinimumHeight() * 4 / 3);
                        setThisDrawable(drawable);
                    }
                }, 80);
                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        drawable.setBounds(0, 0, drawable.getMinimumWidth() * 6 / 5, drawable.getMinimumHeight() * 6 / 5);
                        setThisDrawable(drawable);
                    }
                }, 90);
                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        drawable.setBounds(0, 0, drawable.getMinimumWidth() * 5 / 4, drawable.getMinimumHeight() * 5 / 4);
                        setThisDrawable(drawable);
                    }
                }, 100);
                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        drawable.setBounds(0, 0, drawable.getMinimumWidth() * 8 / 7, drawable.getMinimumHeight() * 8 / 7);
                        setThisDrawable(drawable);
                    }
                }, 110);
                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight());
                        setThisDrawable(drawable);
                    }
                }, 120);
            }
        }
    }


    /**
     * 设置drawable
     */
    public void setDrawables(Drawable left, Drawable top,
                             Drawable right, Drawable bottom) {
        if (null != left) {
            left.setBounds(0, 0, left.getMinimumWidth(), left.getMinimumHeight());
            this.setCompoundDrawables(left, null, null, null);
            isSetNewDrawable = true;
        }
    }

    private void setThisDrawable(Drawable drawable) {
        if (null != drawable && !isSetNewDrawable) {
            this.setCompoundDrawables(drawable, null, null, null);
        }
    }
}
